"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
// ------------------------一、类型--------------------------------
// 1.1 布尔类型
var flag = true;
console.log('布尔类型', 'var flag:boolean=true', flag);
// 1.2 数字类型
var num = 123;
console.log('数字类型', 'var num:number=123', num);
// 1.3 字符串类型
var str = "this is ts";
console.log('字符串leix', 'var str:string("this is ts")', str);
// 1.4 数组类型（array）ts中定义数组有两种方式
// 1、第一种方式
var arr = [1, 2, 3, 4, 5];
console.log('数组定义方式', 'let arrar:numer[]=[1,2,3,4,5]', arr);
var arr2 = ["php", "js", "go"];
console.log('数组定义方式', 'let arr2:string[]=["php", "js", "go"]', arr2);
// 第二种方式
var arr3 = [1, 2, 3, 4];
console.log('数组定义方式2', "let arr:Array<number>=[1,2,3,4]", arr3);
var arr4 = ["pgh", "js"];
console.log('数组定义方式3', 'let arr4:Array<string>=["php", "js"]', arr4);
// 1.5 元组类型（tuple）
var arr5 = ["ts", 12, false];
console.log('元组', 'let arr5:[string, number, boolean]', arr5);
// 1.6 枚举类型
var Flag;
(function (Flag) {
    Flag[Flag["success"] = 1] = "success";
    Flag[Flag["error"] = -1] = "error";
})(Flag || (Flag = {}));
var f = Flag.success;
var f2 = Flag.error;
console.log('枚举', 'enum Flag {success=1, error=-1}', f, f2);
var Color;
(function (Color) {
    Color[Color["blue"] = 0] = "blue";
    Color[Color["yellow"] = 1] = "yellow";
    Color[Color["green"] = 2] = "green";
})(Color || (Color = {}));
var color = Color.yellow;
console.log('enum Color {blue, yellow, green}', color);
// 1.7 任意类型
var anyt = 34;
anyt = "3443";
console.log(anyt);
// 1.8 null 和 undefine 其他类型（never类型）子类型
var ud;
console.log(ud);
// 1.9 多重类型
var num2;
console.log(num2);
var num3 = null;
console.log(num3);
var num4;
console.log(num4);
// ---------------------------二、方法------------------------------
// 2.1 声明函数：方法无返回值，使用void类型
function run() {
    console.log('run method done');
}
run();
// 2.2 匿名函数：方法有返回值，使用对应的类型
var fun2 = function () {
    return 123;
};
console.log(fun2());
// 2.3 ts 函数参数
function getInfo(name, age) {
    return name + "\u4ECA\u5E74" + age + "\u5C81\u4E86";
}
console.log('ts带参函数getInfo', getInfo('jojo', 24));
// 2.4 可选参数 ?
function getInfo2(name, age) {
    if (age) {
        return name + "\u4ECA\u5E74" + age + "\u5C81\u4E86";
    }
    else {
        return name + "\u7684\u5E74\u9F84\u4FDD\u5BC6";
    }
}
console.log(getInfo2("jojoli"));
// 2.5 默认参数
function getInfo3(name, age) {
    if (age === void 0) { age = 18; }
    return name + "\u4ECA\u5E74" + age + "\u5C81\u4E86";
}
console.log(getInfo3('kk'));
// 2.6 剩余参数 变长参数，只能在最后一位，有且只有一个
function sum(sum) {
    var result = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        result[_i - 1] = arguments[_i];
    }
    for (var i = 0; i < result.length; ++i) {
        sum += result[i];
    }
    return sum;
}
console.log('剩余参数', sum(100, 1, 2, 3, 4, 5));
function multiImpl(str, age) {
    if (age) {
        return "\u6211\u53EB" + str + "\u5E74\u9F84\u662F" + age;
    }
    else {
        return "\u6211\u53EB" + str;
    }
}
console.log(multiImpl('jojo'));
console.log(multiImpl('jojo', 123));
// 2.8 箭头函数
setTimeout(function () {
    console.log('箭头函数');
}, 1000);
// ---------------------------三、类----------------------------------
// 3.1 类的定义
var Person = /** @class */ (function () {
    function Person(name) {
        this.name = name;
    }
    Person.prototype.run = function () {
        return 'Person类实例run方法';
    };
    Person.prototype.getName = function () {
        return this.name;
    };
    Person.prototype.setName = function (name) {
        this.name = name;
    };
    return Person;
}());
var p = new Person('jojo');
console.log(p.run());
p.setName('jojoli');
console.log(p.getName());
// 3.2 ts中实现类的继承 extends、super
// 父类和子类中有同样的方法，子类调用子类中的方法（重写）
var SubPerson = /** @class */ (function (_super) {
    __extends(SubPerson, _super);
    function SubPerson(name, age) {
        var _this = _super.call(this, name) || this;
        _this.age = age;
        return _this;
    }
    SubPerson.prototype.run = function () {
        return this.name + "\u4ECA\u5E74" + this.age + ",\u73B0\u5728\u5728\u8FD0\u52A8";
    };
    return SubPerson;
}(Person));
var p2 = new SubPerson('dj', 23);
console.log(p2.run());
// 3.3 类属性的修饰符  
/**
 * public 公有。在类里面、子类、类外面都可以访问
 * protected：保护类型，在类里面、子类里面可以访问，在类外面没法访问
 * privated： 私有 在类里面可以访问，子类和类外面不能访问
 *
 * super不能访问父类非public属性
 * 属性不写修饰符，默认是public
 */
// 略 自行验证
// 3.4 静态属性 静态方法 static 关键字
var StaticT = /** @class */ (function () {
    function StaticT() {
    }
    StaticT.sayHello = function (str) {
        return 'static method:' + str;
    };
    StaticT.message = "static message";
    return StaticT;
}());
console.log(StaticT.sayHello('dj'));
console.log(StaticT.message);
// 3.5 多态： 父类定义各一方法，让子类去实现，每个子类有不同的表现
var Animal = /** @class */ (function () {
    function Animal(name) {
        this.name = name;
    }
    return Animal;
}());
var Dog = /** @class */ (function (_super) {
    __extends(Dog, _super);
    function Dog(name) {
        return _super.call(this, name) || this;
    }
    Dog.prototype.eat = function () {
        console.log(this.name + "\u5403\u7C91\u7C91");
    };
    return Dog;
}(Animal));
var Cat = /** @class */ (function (_super) {
    __extends(Cat, _super);
    function Cat(name) {
        return _super.call(this, name) || this;
    }
    Cat.prototype.eat = function () {
        console.log(this.name + "\u5403\u732B\u7CAE");
    };
    return Cat;
}(Animal));
var cat = new Cat('速八的猫');
cat.eat();
function printName(name) {
    if (name.title) {
        console.log(name.title + ": " + name.fistName + "\u00B7" + name.lastName);
    }
    else {
        console.log(name.fistName + "\u00B7" + name.lastName);
    }
}
var obj = { fistName: '阿莱克斯', lastName: '塔萨', title: '生命的缚誓者', str: 'hihi' };
printName(obj); // 包含接口属性就行
printName({ fistName: '阿莱克斯', lastName: '塔萨', title: '生命的缚誓者' }); // 只能包含接口属性
// 4.1.2 接口：可选属性
printName({ fistName: '跳蛙', lastName: '骑士' }); // 只能包含接口属性
var md5 = function (key, value) {
    // 模拟操作
    return key + value + key;
};
var sha1 = function (key, value) {
    // 模拟操作
    return value + key + value;
};
console.log('函数类型接口', md5('jojo', 'li'), sha1('鹦鹉', '瑞文'));
var userArr = ['123', '1233'];
console.log('可索引接口-数组', userArr[0]);
var userObj = { name: '20', age: '23' }; // 只能是字符串
var Dragon = /** @class */ (function (_super) {
    __extends(Dragon, _super);
    function Dragon(name) {
        return _super.call(this, name) || this;
    }
    Dragon.prototype.eat = function () {
        console.log(this.name + "\u5403buff");
    };
    Dragon.prototype.move = function (desc) {
        console.log(this.name + "\u7528\u7FC5\u8180\u98DE\u5230" + desc);
    };
    return Dragon;
}(Animal));
var flyD = new Dragon('走地龙');
flyD.move('圣山');
var dragon = new Dragon('青铜龙');
dragon.eat();
var d = new Dragon('精灵龙');
d.eat();
// -------------------------------------五、泛型-----------------------------------
// any 放弃类型检查， 泛型可以规范传入类型和返回类型
// 5.1 泛型方法
function getData(value) {
    return value;
}
console.log('getData泛型', getData('2323'));
console.log('getData泛型', getData(233));
// 5.2 泛型类
var RandomListClass = /** @class */ (function () {
    function RandomListClass() {
        this.list = [];
    }
    RandomListClass.prototype.add = function (num) {
        this.list.push(num);
    };
    RandomListClass.prototype.get = function () {
        // 略
        return this.list[Math.floor(Math.random() * this.list.length)];
    };
    return RandomListClass;
}());
var m = new RandomListClass();
m.add(4555555555);
m.add(222222223);
m.add(345);
m.add(-3444444444444);
console.log('泛型类，随机值', m.get());
var m2 = new RandomListClass();
m2.add('jojoli');
m2.add('dj');
m2.add('ly');
m2.add('jg');
console.log('泛型类，随机值', m2.get());
var fnT = function getData(value) {
    return value;
};
var instanceF = fnT;
console.log(instanceF('42'));
var MysqlDb = /** @class */ (function () {
    function MysqlDb() {
    }
    MysqlDb.prototype.add = function (info) {
        console.log(info);
        return true;
        throw new Error("Method not implemented.");
    };
    MysqlDb.prototype.update = function (info, id) {
        throw new Error("Method not implemented.");
    };
    MysqlDb.prototype.delete = function (id) {
        throw new Error("Method not implemented.");
    };
    MysqlDb.prototype.get = function (id) {
        throw new Error("Method not implemented.");
    };
    return MysqlDb;
}());
var MsSqlDb = /** @class */ (function () {
    function MsSqlDb() {
    }
    MsSqlDb.prototype.add = function (info) {
        console.log(info);
        return true;
    };
    MsSqlDb.prototype.update = function (info, id) {
        throw new Error("Method not implemented.");
    };
    MsSqlDb.prototype.delete = function (id) {
        throw new Error("Method not implemented.");
    };
    MsSqlDb.prototype.get = function (id) {
        throw new Error("Method not implemented.");
    };
    return MsSqlDb;
}());
var User = /** @class */ (function () {
    function User() {
    }
    return User;
}());
var u = new User();
u.username = 'jojo';
u.password = '34';
var oMssql = new MsSqlDb();
oMssql.add(u);
// ----------------------------七、模块化-----------------------------
var db_1 = require("./modules/db");
var db = new db_1.MsSqlDb();
console.log(db.add(23333));
// 使用 node js/index.js 进行显示结果
// ----------------------------八、命名空间化-----------------------------------
// 避免命名冲突
var nsp_1 = require("./modules/nsp");
var cat2 = new nsp_1.A.Cat('速八的猫');
cat2.eat();
var cat3 = new nsp_1.B.Cat('速八的猫');
cat3.eat();
// ------------------------------九、装饰器-------------------------------
// 9.1.2 类装饰器
function logClass(params) {
    console.log(params);
    params.prototype.apiUrl = "fsfs";
}
var HttpClient = /** @class */ (function () {
    function HttpClient() {
    }
    HttpClient.prototype.getData = function () {
    };
    HttpClient = __decorate([
        logClass
    ], HttpClient);
    return HttpClient;
}());
var http = new HttpClient();
console.log(http.apiUrl);
// 9.1.1 装饰器工厂
function logClass2(params) {
    return function (target) {
        console.log(target);
        console.log(params);
        target.prototype.apiUrl = params;
    };
}
var HttpClient2 = /** @class */ (function () {
    function HttpClient2() {
    }
    HttpClient2.prototype.getData = function () {
    };
    HttpClient2 = __decorate([
        logClass2("http://www.bilibili.com")
    ], HttpClient2);
    return HttpClient2;
}());
var http2 = new HttpClient2();
console.log(http2.apiUrl);
// 9.1.3 类装饰器重载构造函数
function logClass3(target) {
    console.log(target);
    return /** @class */ (function (_super) {
        __extends(class_1, _super);
        function class_1() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.apiUrl = '我是修改后的数据';
            return _this;
        }
        class_1.prototype.getData = function () {
            console.log(this.apiUrl);
        };
        return class_1;
    }(target));
}
var HttpClient3 = /** @class */ (function () {
    function HttpClient3() {
        this.apiUrl = "我是构造函数中的url";
    }
    HttpClient3.prototype.getData = function () {
        console.log(this.apiUrl);
    };
    HttpClient3 = __decorate([
        logClass3
    ], HttpClient3);
    return HttpClient3;
}());
var http3 = new HttpClient3();
http3.getData();
// 9.2 属性装饰器
// 类装饰器
function logClass4(params) {
    return function (target) {
        console.log(target);
        console.log(params);
    };
}
// 属性装饰器
function logProperty(params) {
    return function (target, attr) {
        console.log('logProperty', target);
        console.log('logProperty', attr);
    };
}
var HttpClient4 = /** @class */ (function () {
    function HttpClient4() {
        this.apiUrl = "我是构造函数中的url";
    }
    HttpClient4.prototype.getData = function () {
        console.log(this.apiUrl);
    };
    __decorate([
        logProperty('baidu.com')
    ], HttpClient4.prototype, "apiUrl", void 0);
    HttpClient4 = __decorate([
        logClass4('xxx')
    ], HttpClient4);
    return HttpClient4;
}());
var http4 = new HttpClient4();
console.log(http4.apiUrl);
// 9.3 方法装饰器 
/**
 * 它会被应用到方法的属性描述上，可以用来监视，修改或者替换方法定义
 *
 * 方法修饰会在运行时传入下列三个参数
 *  1、对于静态成员来说是类的构造函数，对于实例成员是类的原型对象
 *  2、成员的名称
 *  3、成员的属性描述符
 */
// 方法装饰器装饰器
function logMethod(params) {
    return function (target, methodName, desc) {
        console.log('logMethod', target);
        console.log('logMethod', methodName);
        console.log('logMethod', desc);
        target.apiUrl = 'xxx';
        target.run = function () {
            console.log('logMethod', 'run');
        };
    };
}
var HttpClient5 = /** @class */ (function () {
    function HttpClient5() {
        this.apiUrl = "我是构造函数中的url";
    }
    HttpClient5.prototype.getData = function () {
        console.log(this.apiUrl);
    };
    __decorate([
        logMethod('hh')
    ], HttpClient5.prototype, "getData", null);
    return HttpClient5;
}());
var http5 = new HttpClient5();
http5.run();
// 方法装饰器修改参数类型
function get(params) {
    return function (target, methodName, desc) {
        console.log('get', target);
        console.log('get', methodName);
        console.log('get', desc);
        // 把装饰器方法里传入的所有参数改为string类型
        var oMethod = desc.value;
        desc.value = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            args = args.map(function (value) {
                return String(value);
            });
            console.log(args);
        };
    };
}
var HttpClient6 = /** @class */ (function () {
    function HttpClient6() {
        this.apiUrl = "我是构造函数中的url";
    }
    HttpClient6.prototype.getData = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        console.log(this.apiUrl);
    };
    __decorate([
        get('hhxhhx')
    ], HttpClient6.prototype, "getData", null);
    return HttpClient6;
}());
var http6 = new HttpClient6();
http6.getData('jojo', 233, false);
// 9.4 方法参数装饰器 
function logParams(params) {
    return function (target, paramsName, paramIndex) {
        console.log('logParams', target);
        console.log('logParams', paramsName);
        console.log('logParams', paramIndex);
        target.apiUrl = params;
    };
}
var HttpClient7 = /** @class */ (function () {
    function HttpClient7() {
        this.apiUrl = "我是构造函数中的url";
    }
    HttpClient7.prototype.getData = function (uuid) {
        console.log(this.apiUrl);
    };
    __decorate([
        __param(0, logParams('uuid'))
    ], HttpClient7.prototype, "getData", null);
    return HttpClient7;
}());
var http7 = new HttpClient7();
http7.getData();
// 装饰器执行顺序
/**
    从里到外，从上到下，从右到左：
        属性装饰器
        方法参数装饰器2
        方法参数装饰器1
        方法装饰器
        类装饰器2
        类装饰器1
 */
var K;
(function (K) {
    function logProperty(params) {
        return function (target, attr) {
            console.log('属性装饰器');
        };
    }
    function logMethod(params) {
        return function (target, methodName) {
            console.log('方法装饰器');
        };
    }
    function logClass(params) {
        console.log('类装饰器1');
    }
    function logClass2(params) {
        console.log('类装饰器2');
    }
    function logParams(params) {
        return function (target, paramsName, paramIndex) {
            console.log('方法参数装饰器1');
        };
    }
    function logParams2(params) {
        return function (target, paramsName, paramIndex) {
            console.log('方法参数装饰器2');
        };
    }
    var HttpClient = /** @class */ (function () {
        function HttpClient() {
        }
        HttpClient.prototype.getData = function (uuid, value) {
            console.log('getData被调用了');
        };
        __decorate([
            logProperty()
        ], HttpClient.prototype, "apiUrl", void 0);
        __decorate([
            logMethod(),
            __param(0, logParams()),
            __param(1, logParams2())
        ], HttpClient.prototype, "getData", null);
        HttpClient = __decorate([
            logClass,
            logClass2
        ], HttpClient);
        return HttpClient;
    }());
    K.HttpClient = HttpClient;
})(K || (K = {}));
// 从里到外，从上到下，从右到左
var http8 = new K.HttpClient();
